package org.bjf.modules.sys.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bjf.cache.CacheNameConfig.RedisCacheEnum.Names;
import org.bjf.modules.core.service.BaseService;
import org.bjf.modules.sys.bean.SysAcl;
import org.bjf.modules.sys.bean.SysMenu;
import org.bjf.modules.sys.bean.SysUserRole;
import org.bjf.modules.sys.enums.AclEnum.PrincipalType;
import org.bjf.modules.sys.enums.AclEnum.ResourceType;
import org.bjf.modules.sys.mapper.SysMenuMapper;
import org.bjf.modules.sys.query.SysAclQuery;
import org.bjf.modules.sys.query.SysMenuQuery;
import org.bjf.modules.sys.query.SysUserRoleQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
 * @author bjf
 * @date 2017/11/27
 */
@Service
@Slf4j
public class SysMenuService extends BaseService<SysMenuMapper, SysMenu, SysMenuQuery> {

  @Autowired
  private SysUserRoleService userRoleService;
  @Autowired
  private SysAclService aclService;

  @Override
  protected LambdaQueryWrapper<SysMenu> buildQuery(SysMenuQuery q) {
    if (q == null) {
      return null;
    }
    LambdaQueryWrapper<SysMenu> qw = new LambdaQueryWrapper<>();
    qw.eq(q.getPid() != null, SysMenu::getPid, q.getPid());
    qw.likeRight(StringUtils.isNotBlank(q.getMenuName()), SysMenu::getMenuName, q.getMenuName());
    return qw;
  }

  /**
   * 查询用户的菜单
   */
  @Cacheable(value = Names.SYS, key = "'live:menu:listByUser:' + #sysUserId")
  public List<SysMenu> listByUser(long sysUserId) {
    //===1.取用户所有角色
    SysUserRoleQuery urQuery = new SysUserRoleQuery()
        .setSysUserId(sysUserId);
    List<SysUserRole> userRoles = userRoleService.listAll(urQuery);

    //===2.查询所有角色的菜单
    return listByRole(
        userRoles.stream().map(SysUserRole::getSysRoleId).collect(Collectors.toList()));
  }

  /**
   * 查询角色的菜单
   */
  public List<SysMenu> listByRole(List<Long> roleIdList) {
    if (roleIdList.isEmpty()) {
      return Collections.emptyList();
    }
    //===1.查询角色的acl菜单资源ID
    SysAclQuery aclQuery = new SysAclQuery()
        .setPrincipalType(PrincipalType.ROLE.getType())
        .setPrincipalIdList(roleIdList)
        .setResourceType(ResourceType.MENU.getType());
    List<SysAcl> aclList = aclService.listAll(aclQuery);
    if (aclList.isEmpty()) {
      return Collections.emptyList();
    }

    //===2.查询菜单
    List<Long> menuIdList = aclList.stream().map(e -> Long.parseLong(e.getResourceId()))
        .collect(Collectors.toList());
    return this.listByIds(menuIdList);
  }
}
